package com.caiyi.financial.nirvana.sms.gateway.http;

import com.alibaba.fastjson.JSON;
import com.caiyi.financial.nirvana.sms.entity.SmsReceiveMessage;
import com.caiyi.financial.nirvana.sms.enums.ReturnCodeEnum;
import com.caiyi.financial.nirvana.sms.enums.SmsMsgStatusEnum;
import com.caiyi.financial.nirvana.sms.jedis.JedisKey;
import com.caiyi.financial.nirvana.sms.jedis.JedisService;
import com.caiyi.financial.nirvana.sms.queue.NotifyQueueEntity;
import com.caiyi.financial.nirvana.sms.queue.ReceiveMsgQueueEntity;
import com.caiyi.financial.nirvana.sms.queue.SendQueueEntity;
import com.caiyi.financial.nirvana.sms.util.HttpClientUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.jdom2.Content;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;

import java.io.IOException;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * \* User: ywg
 * \* Date: 2018/4/10
 * \* Time: 11:31
 * \* Description:
 * \
 */
public class YunxinGateway extends BaseGateway {
    private static final Logger logger = LoggerFactory.getLogger(YunxinGateway.class);

    @Override
    public void sendMessage(SendQueueEntity entity) {
        int status = SmsMsgStatusEnum.REQUEST_FAIL.index;
        String result = "";
        try {
            Map param = buildParam(entity);
            String response = doPost(info.getServerAddr(), param);
            String[] split = entity.getMessageId().split(",");
            if (response == null) {
                result = "网关请求超时";
                status = SmsMsgStatusEnum.REQUEST_FAIL.index;
                for (String messageId : split) {
                    receiveReport(status, messageId, result);
                }
                return;
            }
            result = xmlElements(response);
            logger.info("YunxinGateway send url : {}, params : {}, response : {}, result : {}", info.getServerAddr(), param, response, result);
            if (result == null || result.length() < 10) {
                return;
            }
            status = SmsMsgStatusEnum.REQUEST_SUCCESS.index;
        } catch (Exception e) {
            logger.error("YunxinGateway sendMessage error ! ", e);
        } finally {
            this.handlerResponse(entity, result, status);
        }

    }

    public String xmlElements(String xmlDoc) {
        if (StringUtils.isBlank(xmlDoc)) {
            return null;
        }
        String value = null;
        StringReader read = null;
        try {
            //创建一个新的字符串
            read = new StringReader(xmlDoc);
            //创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
            InputSource source = new InputSource(read);
            //创建一个新的SAXBuilder
            SAXBuilder sb = new SAXBuilder();
            //通过输入源构造一个Document
            Document doc = sb.build(source);
            //取的根元素
            Element root = doc.getRootElement();
            //得到根元素所有子元素的集合
            List<Content> content = root.getContent();
            if (content != null) {
                Content content1 = content.get(0);
                value = content1.getValue();
            }
        } catch (JDOMException e) {
            logger.error("YunxinGateway xmlElements  dom error ! ", e);
        } catch (IOException e) {
            logger.error("YunxinGateway xmlElements  dom error ! ", e);
        } finally {
            read.close();
        }
        return value;
    }

    private Map buildParam(SendQueueEntity entity) throws Exception {
        String content = entity.getContent();
        String customStr = info.getCustom();
        boolean before = content.startsWith("【");
        if (before) {
            String signOld = content.substring(0, content.indexOf("】") + 1);
            content = content.replace(signOld, "");
            content = content + signOld;
        }
        if (StringUtils.isNotBlank(customStr)) {
            Map custom = JSON.parseObject(customStr, Map.class);
            String signOld = content.substring(content.lastIndexOf("【"));
            String signNew = (String) custom.get(signOld);
            if (StringUtils.isNotBlank(signNew)) {
                content = content.replace(signOld, signNew);
            }
        }
        logger.info("content is {}", content);
        Map<String, String> map = new HashMap<>();
        map.put("userCode", info.getAccount());
        map.put("userPass", info.getPassword());
        map.put("Msg", content);
        map.put("DesNo", entity.getPhone());
        String channel = StringUtils.isBlank(info.getAccessNumber()) ? "0" : info.getAccessNumber();
        map.put("Channel", channel);

        return map;
    }

    @Override
    public boolean notifyStatus(NotifyQueueEntity entity) {
        try {
            String param = entity.getParam();
            logger.info("YunxinGateway notifyStatus param : {}", param);
            Map<String, String> paramMap = JSON.parseObject(param, Map.class);
            String report = paramMap.get("GetReport");
            String[] items = report.split("\\|");
            for (String item : items) {
                int status = SmsMsgStatusEnum.SEND_FAIL.index;
                String[] split = item.split(",");
                String remoteId = split[0];
                String phone = split[1];
                String result = split[2];
                if ("DELIVRD".equals(result)) {
                    status = SmsMsgStatusEnum.SEND_SUCCESS.index;
                }
                String messageId = JedisService.hget(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteId + phone);
                JedisService.hdel(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, remoteId + phone);
                if (StringUtils.isBlank(messageId)) {
                    logger.warn("YunxinGateway notifyStatus messageId is null params : {}", param);
                }
                receiveReport(status, messageId, result);
            }
            return true;
        } catch (Exception e) {
            logger.error("YunxinGateway notifyStatus error ! ", e);
        }
        return false;
    }

    @Override
    public boolean receiveMsg(ReceiveMsgQueueEntity entity) {
        try {
            String param = entity.getParam();
            logger.info("YunxinGateway receiveMsg param : {}", param);
            Map<String, String> paramMap = JSON.parseObject(param, Map.class);
            SmsReceiveMessage smsReceiveMessage = new SmsReceiveMessage();
            String getMo = paramMap.get("GetMo");
            if (getMo != null) {
                String[] split = getMo.split("\\|;\\|");
                if (split != null && split[0] != null) {
                    String[] item = split[0].split("\\|,\\|");
                    smsReceiveMessage.setCreateTime(new Date());
                    smsReceiveMessage.setPhone(item[0]);
                    smsReceiveMessage.setContent(item[1]);
                    String extend = item[3].substring(item[3].length() - 3);
                    String account = JedisService.get(String.format(JedisKey.SMS_EXTEND_ACCOUNT, extend));
                    smsReceiveMessage.setAccount(account);
                    smsReceiveMessage.setAccessNumber(item[3]);
                    smsReceiveMessage.setMessageId(item[3]);
                    receiveMessage(smsReceiveMessage);
                }
            }
            return true;
        } catch (Exception e) {
            logger.error("YunxinGateway receiveMsg error ! ", e);
        }
        return false;
    }

    @Override
    public int queryBalance() throws Exception {
        try {
            StringBuilder builder = new StringBuilder(info.getServerAddr().replaceFirst("SendMsg", "GetBalance"));
            builder.append("?userCode=").append(info.getAccount());
            builder.append("&userPass=").append(info.getPassword());
            String response = HttpClientUtil.doGet(builder.toString());
            logger.info("{}余额查询结果:{}", info.getName(), response);
            String elements = xmlElements(response);
            if ((StringUtils.isNotBlank(elements) && StringUtils.isBlank(info.getAccessNumber())) || NumberUtils.toDouble(elements) < 0) {
                return Integer.parseInt(elements);
            }
            BigDecimal bd = new BigDecimal(NumberUtils.toDouble(elements) * 1000 / info.getServerPort()).setScale(0, BigDecimal.ROUND_HALF_UP);
            return Integer.parseInt(bd.toString());
        } catch (Exception e) {
            logger.error("YunxinGateway queryBalance error ! ", e);
        }
        return 0;
    }

}
